﻿using System;
using System.Collections.Generic;
using System.Text;
using DevExpress.ExpressApp.DC;
using DevExpress.Persistent.Base;
using DevExpress.Xpo;
using DevExpress.Persistent.Validation;
using DevExpress.ExpressApp;
using DevExpress.Data.Filtering;

namespace DomainComponents.XCRM {

    public class SaleItemValidationRules {
        public const string ProductIsRequired = "ProductIsRequired";
        public const string QuantityIsGreaterThanOrEqualZero = "QuantityIsGreaterThanOrEqualZero";
        public const string DiscountIsGreaterThanOrEqualZero = "DiscountIsGreaterThanOrEqualZero";
    }

    [DomainComponent, NavigationItem(false)]
    [XafDisplayName("Sale Item")]
    public interface ISaleItem {
        [VisibleInListView(false)]
        ISaleBase saleBase { get; set; }

        [RuleRequiredField(SaleItemValidationRules.ProductIsRequired, DefaultContexts.Save)]
        [ImmediatePostData]
        IProduct Product { get; set; }
        
        [RuleValueComparison(SaleItemValidationRules.QuantityIsGreaterThanOrEqualZero, DefaultContexts.Save, ValueComparisonType.GreaterThanOrEqual, 0)]
        [ImmediatePostData]
        int Quantity { get; set; }
        
        [RuleValueComparison(SaleItemValidationRules.DiscountIsGreaterThanOrEqualZero, DefaultContexts.Save, ValueComparisonType.GreaterThanOrEqual, 0)]
        [ImmediatePostData]
        decimal Discount { get; set; }
        
        decimal Amount { get; set; }
        
        void UpdateAmount();
    }

    [DomainLogic(typeof(ISaleItem))]
    public class SaleItemLogic {
        public virtual decimal GetProductPrice(ISaleItem saleItem) {
            // supporting method to implement price lists. Dan.
            return saleItem.Product.Price;
        }
        public virtual void UpdateAmount(ISaleItem saleItem) {
            if(saleItem.Product != null) {
                saleItem.Amount = (GetProductPrice(saleItem) * saleItem.Quantity) - saleItem.Discount;
            }
            else {
                saleItem.Amount = 0;
            }
            if(saleItem.saleBase != null) {
                saleItem.saleBase.UpdateAmount();
            }
        }
        public static void AfterChange_Product(ISaleItem saleItem){
            saleItem.UpdateAmount();
        }
        
        public static void AfterChange_Quantity(ISaleItem saleItem){
            saleItem.UpdateAmount();
        }
        
        public static void AfterChange_Discount(ISaleItem saleItem){
            saleItem.UpdateAmount();
        }
    }
}
